function pMap(list, mapper, concurrency = Infinity) {
    return new Promise((resolve, reject) => {
        let currentIndex = 0;
        let result = [];
        let resolveCount = 0;
        let len = list.length;
        function next() {
            const index = currentIndex++
            Promise.resolve(list[index]).then(o => mapper(o, index)).then(o => {
                result[index] = o;
                if (++resolveCount === len) resolve(result)
                if (currentIndex < len) next()
            })
        }
        for (let i = 0; i < concurrency && i < len; i++) {
            next();
        }
    })
}

function add (x, y) {
    return Promise.resolve(x + y)
  }

function chunk (list, size) {
    const l = []
    for (let i = 0; i < list.length; i++ ) {
      const index = Math.floor(i / size)
      l[index] ? l[index] : l[index] = [];
      l[index].push(list[i])
    }
    console.log('l',l)
    return l
  }

async function sum(arr, concurrency) {
    if (arr.length === 1) return arr[0]
    return pMap(chunk(arr, 2), ([x, y]) => {
        return y === undefined ? x : add(x, y)
    }, concurrency).then(list => sum(list, concurrency))
}


console.log(sum([1,2,3,4,5,6,7,8,9],0))